package main

import (
	"bufio"
	"config"
	"fmt"
	"github.com/cihub/seelog"
	"github.com/go-redis/redis"
	"io"
	"math"
	"os"
	"public"
	"runtime"
	"sync"
	"syscall"
	"time"
)

var queryChan chan string

// var queryResult sync.Map
var logger seelog.LoggerInterface
var wg sync.WaitGroup //定义一个同步等待的组
var num int
var rdsCli *redis.Client

func LoadTaskFile(fileName string) {
	fi, err := os.Open(fileName)
	if err != nil {
		panic(err)
	}
	defer fi.Close()

	br := bufio.NewReader(fi)
	for {
		bt, _, err := br.ReadLine()
		if err == io.EOF {
			break
		}

		if len(bt) != 32 {
			continue
		}
		imeiMd5 := string(bt)
		fmt.Println(imeiMd5)
		queryChan <- imeiMd5
		num++
	}
}

func Query(cycle int) {
	defer wg.Done()
	var exitFlag bool
	for !exitFlag {
		select {
		case imeiMd5 := <-queryChan:
			imei := public.QueryMd5Imei(rdsCli, cycle, imeiMd5)
			if imei == 0 {
				logger.Infof("query %s failed", imeiMd5)
			} else {
				logger.Infof("query %s %d ok", imeiMd5, imei)
			}
		case <-time.After(100 * time.Second):
			exitFlag = true
			break
		}
	}
}

func setQueryLogger() (err error) {
	logxml := `<seelog>
    <outputs formatid="runtime">
        <buffered formatid="runtime" size="10000" flushperiod="100">
            <rollingfile type="date" filename="./log/query.log" datepattern="2006-01-02-15" maxrolls="240"/>
        </buffered>
    </outputs>
    <formats>
        <format id="runtime" format="%Date %Time:	%Msg%n"/>
    </formats>
</seelog>`
	logger, err = seelog.LoggerFromConfigAsBytes([]byte(logxml))
	return err
}

func watch() {
	for {
		time.Sleep(time.Minute)
		logger.Infof("run current cycle num[%d]", num)
	}
}

func main() {
	if len(os.Args) < 2 {
		fmt.Println("useage: query input_file")
		syscall.Exit(-1)
	}
	taskFile := os.Args[1]

	cfg, err := config.Init("./conf/conf.json")
	if err != nil {
		fmt.Println(err.Error())
		syscall.Exit(-1)
	}

	err = setQueryLogger()
	if err != nil {
		fmt.Printf("setLogger error[%s]\n", err.Error())
		syscall.Exit(-1)
	}

	address := fmt.Sprintf("%s:%d", cfg.RdsHost, cfg.RdsPort)
	fmt.Println(address)
	rdsCli = redis.NewClient(&redis.Options{
		Addr:     address,
		Password: cfg.RdsPassword,
		DB:       cfg.RdsDb,
	})

	funcCycles := 3000000000000 / cfg.Cycles
	queryChan = make(chan string, 100)
	num = 0

	go LoadTaskFile(taskFile)
	go watch()

	for i := 0; i < runtime.NumCPU(); i++ {
		go Query(funcCycles)
		logger.Infof("start run %d groutine", i)
		wg.Add(1)
	}
	wg.Wait()
	logger.Info("query exit")
	rdsCli.Close()
	close(queryChan)
}
